home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / intuisup.lha / Intuisup / source.lha / Gadgets / gadgets4.asm < prev    next >
Assembly Source File  |  1992-07-11  |  8KB  |  252 lines

  1.  * $Revision Header *** Header built automatically - do not edit! **********
  2.  *
  3.  *    (C) Copyright 1991 by Torsten Jürgeleit
  4.  *
  5.  *    Name .....: gadgets4.asm
  6.  *    Created ..: Thursday 19-Dec-91 21:34:12
  7.  *    Revision .: 1
  8.  *
  9.  *    Date        Author                 Comment
  10.  *    =========   ====================   ====================
  11.  *    01-Jul-92   Torsten Jürgeleit      corrected slider bug -> sometimes
  12.  *                       clicking inside of slider gadget
  13.  *                       container don't move the knob
  14.  *                       inside of slider gadget container
  15.  *    19-Dec-91   Torsten Jürgeleit      Created this file!
  16.  *
  17.  ***************************************************************************
  18.  *
  19.  * Proportional gadget support routines (32 bit !!!)
  20.  *
  21.  * $Revision Header ********************************************************
  22.  
  23. *---------------------------------------------------------------------------
  24. * USHORT calc_prop_body(ULONG max_num, ULONG size)
  25. *  d0.w                         d0.l         d1.l
  26. * Calculate the body value for the PropInfo structure
  27. *---------------------------------------------------------------------------
  28.     XDEF    _calc_prop_body
  29. _calc_prop_body:
  30.     movem.l    d2-d6,-(sp)
  31.  
  32.     ; --- check max_num
  33.     move.l    d0,d6        ; save max_num in d6
  34.     beq    cpb_maximum    ; max_num == 0 ?
  35.     cmp.l    d0,d1        ; size >= max_num ?
  36.     bhs    cpb_maximum
  37.  
  38.     ; --- multiply size [32 bit] by MAXBODY ($ffff) [16 bit] with 48 bit arithmetic
  39.     moveq    #0,d0        ; clear shift out reg for size
  40.     move.l    d1,d3        ; init result by doing the first add
  41.     moveq    #0,d2        ; clear shift out reg of result
  42.     moveq    #16-2,d4    ; init shift count (MAXBODY has only 16 bits - one add already done)
  43.  
  44. cpb_mul_loop:
  45.     ; --- shift size
  46.     add.l    d1,d1        ; shift left of size
  47.     addx.w    d0,d0        ; save shift out
  48.  
  49.     ; --- inc result
  50.     add.l    d1,d3        ; add shifted size to result
  51.     addx.w    d0,d2        ; add shift out and carry
  52.     dbra    d4,cpb_mul_loop
  53.  
  54.     ; --- divide result [48 bit] by max_num [32 bit] with 48 bit arithmetic
  55.     moveq    #0,d0        ; clear result
  56.     moveq    #0,d1        ; clear shift out reg for divident
  57.     moveq    #0,d4        ; clear sub divisor help reg
  58.     moveq    #32-1,d5    ; init shift count
  59.  
  60. cpb_div_loop:
  61.     ; --- shift result and divident
  62.     add.l    d0,d0        ; shift result
  63.     add.l    d3,d3        ; shift left of lower LONG of divident
  64.     addx.l    d2,d2        ; shift left of upper LONG of divident - add shift out
  65.     addx.w    d1,d1        ; save shift out
  66.  
  67.     ; --- check if upper LONG of divident large enough to sub divisor from
  68.     tst.w    d1        ; any shift out ?
  69.     bne    cpb_sub_divisor
  70.     cmp.l    d2,d6        ; upper LONG of divident > divisor ?
  71.     bhi    cpb_next_div
  72.  
  73. cpb_sub_divisor:
  74.     sub.l    d6,d2        ; sub divisor from upper LONG of divident
  75.     subx.w    d4,d1        ; sub underflow (d4 = 0) from shift out of upper LONG of divident
  76.     addq.l    #1,d0        ; set bit 0 of result
  77.     
  78. cpb_next_div:
  79.     dbra    d5,cpb_div_loop
  80.  
  81.     ; --- don't return ZERO as prop_body
  82.     tst.w    d0
  83.     bne    cpb_exit
  84.     moveq    #1,d0
  85.     
  86. cpb_exit:
  87.     movem.l    (sp)+,d2-d6
  88.     rts
  89.  
  90. cpb_maximum:
  91.     move.l    #$ffff,d0    ; prop_body := MAXBODY
  92.     bra    cpb_exit
  93.  
  94.  
  95. *---------------------------------------------------------------------------
  96. * USHORT calc_prop_pot(ULONG max_num, ULONG size, ULONG num)
  97. *  d0.w                        d0.l         d1.l        d2.l
  98. * Calculate the prop value for the PropInfo structure
  99. *---------------------------------------------------------------------------
  100.     XDEF    _calc_prop_pot
  101. _calc_prop_pot:
  102.     movem.l    d3-d6,-(sp)
  103.  
  104.     ; --- prepare max_num
  105.     move.l    d0,d6        ; save max_num
  106.     beq    cpp_minimum
  107.     sub.l    d1,d6        ; max_num -:= size
  108.     bcs    cpp_minimum
  109.  
  110.     ; --- multiply num [32 bit] by MAXPOT ($ffff) [16 bit] with 48 bit arithmetic
  111.     moveq    #0,d0        ; clear shift out reg for size
  112.     move.l    d2,d1        ; init num
  113.     move.l    d1,d3        ; init result by doing the first add
  114.     moveq    #0,d2        ; clear shift out reg of result
  115.     moveq    #16-2,d4    ; init shift count (MAXPOT has only 16 bits - one add already done)
  116.  
  117. cpp_mul_loop:
  118.     ; --- shift num
  119.     add.l    d1,d1        ; shift left of num
  120.     addx.w    d0,d0        ; save shift out
  121.  
  122.     ; --- inc result
  123.     add.l    d1,d3        ; add shifted num to result
  124.     addx.w    d0,d2        ; add shift out and carry
  125.     dbra    d4,cpp_mul_loop
  126.     ext.l    d2        ; expand upper WORD to LONG
  127.  
  128.     ; --- divide result [48 bit] by (max_num - size) [32 bit] with 48 bit arithmetic
  129.     moveq    #0,d0        ; clear result
  130.     moveq    #0,d1        ; clear shift out reg for divident
  131.     moveq    #0,d4        ; clear sub divisor help reg
  132.     moveq    #32-1,d5    ; init shift count
  133.  
  134. cpp_div_loop:
  135.     ; --- shift result and divident
  136.     add.l    d0,d0        ; shift result
  137.     add.l    d3,d3        ; shift left of lower LONG of divident
  138.     addx.l    d2,d2        ; shift left of upper LONG of divident - add shift out
  139.     addx.w    d1,d1        ; save shift out
  140.  
  141.     ; --- check if upper LONG of divident large enough to sub divisor from
  142.     tst.w    d1        ; any shift out ?
  143.     bne    cpp_sub_divisor
  144.     cmp.l    d2,d6        ; upper LONG of divident > divisor ?
  145.     bhi    cpp_next_div
  146.  
  147. cpp_sub_divisor:
  148.     sub.l    d6,d2        ; sub divisor from upper LONG of divident
  149.     subx.w    d4,d1        ; sub underflow (d4 = 0) from shift out of upper LONG of divident
  150.     addq.l    #1,d0        ; set bit 0 of result
  151.     
  152. cpp_next_div:
  153.     dbra    d5,cpp_div_loop
  154.  
  155.     ; --- if pot_value > MAXPOT then return MAXPOT
  156.     cmp.l    #$ffff,d0
  157.     bls    cpp_exit
  158.     move.l    #$ffff,d0    ; prop_pot := MAXPOT
  159.  
  160. cpp_exit:
  161.     movem.l    (sp)+,d3-d6
  162.     rts
  163.  
  164. cpp_minimum:
  165.     moveq    #0,d0        ; prop_pot := 0
  166.     bra    cpp_exit
  167.  
  168.  
  169. *---------------------------------------------------------------------------
  170. * ULONG get_prop_pos(ULONG max_num, ULONG size, UWORD pot_value)
  171. *  d0.l                      d0.l         d1.l           d2.w
  172. * Calculate the position of the knob of a proporitional gadget
  173. *---------------------------------------------------------------------------
  174.     XDEF    _get_prop_pos
  175. _get_prop_pos:
  176.     movem.l    d3-d6,-(sp)
  177.  
  178.     ; --- prepare max_num
  179.     sub.l    d1,d0        ; max_num -:= size
  180.     bcs    gpp_minimum
  181.  
  182.     ; --- if pot_value ]0..MAXPOT[ then inc pot_value and max_num
  183.     move.w    d2,d6        ; save pot value
  184.     beq    gpp_minimum    ; pot_value == 0 ?
  185.     addq.w    #1,d6        ; inc pot_value
  186.     bcs    gpp_exit    ; if pot_value == MAXPOT then return (max_num - size)
  187.  
  188.     ; --- multiply (max_num - size) [32 bit] by pot_value [16 bit] with 48 bit arithmetic
  189.     moveq    #0,d1        ; clear shift out reg for max_num
  190.     moveq    #0,d3        ; clear result
  191.     moveq    #0,d2        ; clear shift out reg of result
  192.     moveq    #0,d4        ; reset bit count
  193.     moveq    #16-1,d5    ; init shift count (16 bits from pot_value)
  194.     bra    gpp_check_bit
  195.  
  196. gpp_mul_loop:
  197.     add.l    d0,d0        ; shift left of max_num
  198.     addx.w    d1,d1        ; save shift out
  199.  
  200. gpp_check_bit:
  201.     ; --- check bit of pot_value
  202.     btst    d4,d6
  203.     beq    gpp_next_mul    ; bit set ?
  204.  
  205.     ; --- if bit set then inc result
  206.     add.l    d0,d3        ; add shifted max_num to result
  207.     addx.w    d1,d2        ; add shift out and carry
  208.  
  209. gpp_next_mul:
  210.     addq.w    #1,d4        ; inc bit count
  211.     dbra    d5,gpp_mul_loop
  212.     ext.l    d2        ; expand upper WORD to LONG
  213.  
  214.     ; --- divide result [48 bit] by MAXPOT ($ffff) [16 bit] with 48 bit arithmetic
  215.     moveq    #0,d0        ; clear result
  216.     moveq    #0,d1        ; clear shift out reg for divident
  217.     moveq    #0,d4        ; clear sub divisor help reg
  218.     moveq    #32-1,d5    ; init shift count
  219.     move.l    #$ffff,d6    ; init divisor (MAXPOT)
  220.  
  221. gpp_div_loop:
  222.     ; --- shift result and divident
  223.     add.l    d0,d0        ; shift result
  224.     add.l    d3,d3        ; shift left of lower LONG of divident
  225.     addx.l    d2,d2        ; shift left of upper LONG of divident - add shift out
  226.     addx.w    d1,d1        ; save shift out
  227.  
  228.     ; --- check if upper LONG of divident large enough to sub divisor from
  229.     tst.w    d1        ; any shift out ?
  230.     bne    gpp_sub_divisor
  231.     cmp.l    d2,d6        ; upper LONG of divident > divisor ?
  232.     bhi    gpp_next_div
  233.  
  234. gpp_sub_divisor:
  235.     sub.l    d6,d2        ; sub divisor from upper LONG of divident
  236.     subx.w    d4,d1        ; sub underflow (d4 = 0) from shift out of upper LONG of divident
  237.     addq.l    #1,d0        ; set bit 0 of result
  238.     
  239. gpp_next_div:
  240.     dbra    d5,gpp_div_loop
  241.  
  242. gpp_exit:
  243.     movem.l    (sp)+,d3-d6
  244.     rts
  245.  
  246. gpp_minimum:
  247.     moveq    #0,d0        ; prop_pos := 0
  248.     bra    gpp_exit
  249.  
  250.  
  251.     END
  252.